import axios from 'axios'
import type { AxiosInstance, AxiosRequestConfig, AxiosResponse, AxiosError } from 'axios'

// 为请求配置扩展可选的跳过错误提示标记
export interface ExtendedAxiosRequestConfig extends AxiosRequestConfig {
  skipErrorNotify?: boolean
}
import notify from '@/utils/notify'

/**
 * 注意：后端已采用标准 RESTful API 设计
 * - 单个资源：直接返回对象 (如: User, Lead, Property)
 * - 列表资源：返回分页对象 {total, items, page, page_size}
 * - 错误响应：使用标准 HTTP 状态码 + {detail: string}
 *
 * 不再使用 {code, msg, data} 包装格式
 */

/**
 * Axios 实例配置
 * 遵循 Vue3 + TypeScript 最佳实践
 */
// 规范化 baseURL，保证以斜杠结尾，避免拼接成 /apiv1 之类错误
const rawBase = import.meta.env.VITE_API_BASE_URL ?? '/api'
const baseURL = rawBase.endsWith('/') ? rawBase : rawBase + '/'

const service: AxiosInstance = axios.create({
  baseURL,
  timeout: 15000,
  headers: {
    'Content-Type': 'application/json;charset=utf-8',
  },
})

/**
 * 请求拦截器
 * 注入 JWT Token
 */
service.interceptors.request.use(
  config => {
    const token = localStorage.getItem('token')
    if (token) {
      config.headers.Authorization = `Bearer ${token}`
    }
    return config
  },
  (error: AxiosError) => {
    console.error('Request error:', error)
    return Promise.reject(error)
  }
)

/**
 * 响应拦截器
 * 统一错误处理
 */
service.interceptors.response.use(
  (response: AxiosResponse<unknown>) => {
    // 保持返回 AxiosResponse，由具体请求方法提取 data
    return response
  },
  (error: AxiosError) => {
    const { response } = error
    const cfg = (error.config || {}) as ExtendedAxiosRequestConfig
    const shouldNotify = !cfg.skipErrorNotify

    if (response) {
      switch (response.status) {
        case 401:
          if (shouldNotify) notify.error('登录状态失效，请重新登录')
          localStorage.removeItem('token')
          window.location.href = '/login'
          break
        case 403:
          if (shouldNotify) notify.error('您没有权限执行该操作')
          break
        case 404:
          if (shouldNotify) notify.error('接口不存在或路径错误')
          break
        case 500:
          if (shouldNotify) notify.error('服务器繁忙，请稍后重试')
          break
        default: {
          const data = response.data as unknown
          let detail: string | undefined
          if (data && typeof data === 'object') {
            const obj = data as { detail?: string; message?: string }
            detail = obj.detail ?? obj.message
          }
          if (shouldNotify) notify.error(detail || '请求失败，请稍后重试')
        }
      }
    } else {
      // 区分连接被拒绝与超时
      const err = error as AxiosError & { code?: string }
      if (err?.code === 'ECONNABORTED') {
        if (shouldNotify) notify.error('请求超时，请检查网络')
      } else {
        if (shouldNotify) notify.error('无法连接服务器，请确认后端是否已启动')
      }
    }

    return Promise.reject(error)
  }
)

export default service

/**
 * 通用请求方法
 * 提供完整 TypeScript 类型支持
 *
 * 注意：后端已统一使用标准 RESTful 响应格式，直接返回数据对象
 * 不再使用 {code, msg, data} 包装格式
 */
export const request = {
  get<T = unknown>(url: string, config?: ExtendedAxiosRequestConfig): Promise<T> {
    return service.get<T>(url, config).then(resp => resp.data)
  },

  post<T = unknown, D = unknown>(url: string, data?: D, config?: ExtendedAxiosRequestConfig): Promise<T> {
    return service.post<T, AxiosResponse<T>, D>(url, data, config).then(resp => resp.data)
  },

  put<T = unknown, D = unknown>(url: string, data?: D, config?: ExtendedAxiosRequestConfig): Promise<T> {
    return service.put<T, AxiosResponse<T>, D>(url, data, config).then(resp => resp.data)
  },

  patch<T = unknown, D = unknown>(url: string, data?: D, config?: ExtendedAxiosRequestConfig): Promise<T> {
    return service.patch<T, AxiosResponse<T>, D>(url, data, config).then(resp => resp.data)
  },

  delete<T = unknown>(url: string, config?: ExtendedAxiosRequestConfig): Promise<T> {
    return service.delete<T>(url, config).then(resp => resp.data)
  },
}
